import pymongo
from datetime import datetime
from collections import defaultdict
import numpy as np
import pandas as pd
from typing import Dict, List, Tuple

# 连接到MongoDB
client = pymongo.MongoClient('mongodb://localhost:27017/')
db = client['test']
logs_collection = db['logs']
books_collection = db['book']


def analyze_user_logs() -> Dict:
    """综合分析用户日志数据"""
    # 1. 获取基础数据
    logs = list(logs_collection.find({}))
    books = list(books_collection.find({}))

    if not logs or not books:
        return {"error": "缺少日志或图书数据"}

    # 2. 基础统计
    total_logs = len(logs)
    unique_users = len({log['u_id'] for log in logs})
    unique_books = len({log['b_id'] for log in logs})

    # 3. 行为分布分析
    action_counts = defaultdict(int)
    for log in logs:
        action_counts[log['action']] += 1

    # 4. 用户活跃度分析
    user_activity = defaultdict(int)
    for log in logs:
        user_activity[log['u_id']] += 1

    # 5. 图书热度分析
    book_popularity = defaultdict(int)
    for log in logs:
        book_popularity[log['b_id']] += 1

    # 6. 时间分布分析
    hourly_activity = defaultdict(int)
    for log in logs:
        hour = log['timestamp'].hour
        hourly_activity[hour] += 1

    # 7. 用户行为路径分析（示例：最后5个用户）
    user_behavior_paths = {}
    sample_users = list(user_activity.keys())[:5]
    for user in sample_users:
        user_logs = sorted([log for log in logs if log['u_id'] == user],
                           key=lambda x: x['timestamp'])
        user_behavior_paths[user] = [log['action'] for log in user_logs]

    # 8. 生成报告
    report = {
        "basic_stats": {
            "total_logs": total_logs,
            "unique_users": unique_users,
            "unique_books": unique_books,
            "log_per_user": round(total_logs / unique_users, 1),
            "log_per_book": round(total_logs / unique_books, 1)
        },
        "action_distribution": dict(sorted(action_counts.items(), key=lambda x: x[1], reverse=True)),
        "user_activity": {
            "most_active_user": max(user_activity.items(), key=lambda x: x[1]),
            "avg_actions_per_user": round(np.mean(list(user_activity.values())), 1),
            "user_activity_distribution": {
                "high": sum(1 for v in user_activity.values() if v > 50),
                "medium": sum(1 for v in user_activity.values() if 20 <= v <= 50),
                "low": sum(1 for v in user_activity.values() if v < 20)
            }
        },
        "book_popularity": {
            "most_popular_books": sorted(book_popularity.items(), key=lambda x: x[1], reverse=True)[:5],
            "least_popular_books": sorted(book_popularity.items(), key=lambda x: x[1])[:5],
            "popularity_distribution": {
                "hot": sum(1 for v in book_popularity.values() if v > 100),
                "medium": sum(1 for v in book_popularity.values() if 30 <= v <= 100),
                "cold": sum(1 for v in book_popularity.values() if v < 30)
            }
        },
        "time_analysis": {
            "peak_hours": sorted(hourly_activity.items(), key=lambda x: x[1], reverse=True)[:3],
            "off_peak_hours": sorted(hourly_activity.items(), key=lambda x: x[1])[:3]
        },
        "sample_behavior_paths": user_behavior_paths,
        "generated_at": datetime.now().isoformat()
    }

    return report


def generate_behavior_report(report_data: Dict) -> pd.DataFrame:
    """生成行为分析报表"""
    # 行为分布
    action_df = pd.DataFrame.from_dict(
        report_data['action_distribution'],
        orient='index',
        columns=['count']
    ).sort_values('count', ascending=False)
    action_df['percentage'] = (action_df['count'] / report_data['basic_stats']['total_logs'] * 100).round(1)

    # 用户活跃度
    user_activity = report_data['user_activity']
    user_stats = {
        "most_active_user": user_activity['most_active_user'],
        "average_actions": user_activity['avg_actions_per_user'],
        "high_activity_users": user_activity['user_activity_distribution']['high'],
        "medium_activity_users": user_activity['user_activity_distribution']['medium'],
        "low_activity_users": user_activity['user_activity_distribution']['low']
    }

    # 图书热度
    book_popularity = report_data['book_popularity']
    book_stats = {
        "most_popular": book_popularity['most_popular_books'],
        "least_popular": book_popularity['least_popular_books'],
        "hot_books": book_popularity['popularity_distribution']['hot'],
        "medium_books": book_popularity['popularity_distribution']['medium'],
        "cold_books": book_popularity['popularity_distribution']['cold']
    }

    # 时间分析
    time_stats = {
        "peak_hours": [f"{h}:00 ({c}次)" for h, c in report_data['time_analysis']['peak_hours']],
        "off_peak_hours": [f"{h}:00 ({c}次)" for h, c in report_data['time_analysis']['off_peak_hours']]
    }

    # 创建综合报表
    summary_df = pd.DataFrame({
        "指标": ["总日志数", "独立用户数", "涉及图书数", "平均每用户行为数", "平均每图书行为数"],
        "值": [
            report_data['basic_stats']['total_logs'],
            report_data['basic_stats']['unique_users'],
            report_data['basic_stats']['unique_books'],
            report_data['basic_stats']['log_per_user'],
            report_data['basic_stats']['log_per_book']
        ]
    })

    return {
        "action_distribution": action_df,
        "user_activity": pd.DataFrame.from_dict(user_stats, orient='index', columns=['值']),
        "book_popularity": pd.DataFrame.from_dict(book_stats, orient='index', columns=['值']),
        "time_analysis": pd.DataFrame.from_dict(time_stats, orient='index', columns=['值']),
        "summary": summary_df
    }


if __name__ == "__main__":
    # 执行分析
    analysis_result = analyze_user_logs()

    # 生成报表
    report = generate_behavior_report(analysis_result)

    # 打印关键结果
    print("=== 基础统计 ===")
    print(report['summary'])

    print("\n=== 行为分布 ===")
    print(report['action_distribution'])

    print("\n=== 用户活跃度 ===")
    print(report['user_activity'])

    print("\n=== 图书热度 ===")
    print(report['book_popularity'])

    print("\n=== 时间分析 ===")
    print(report['time_analysis'])

    # 保存完整报告到MongoDB
    db['log_analysis'].insert_one({
        "analysis_date": datetime.now(),
        "report": analysis_result
    })
    print("\n分析结果已保存到MongoDB的log_analysis集合")